package cn.jietuo.juc.c_014_containers;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhangx & jietuo_zx@163.com
 * @version 1.0
 * @date 2021/1/14
 * @description: 测试map的读写效率
 */
public class T1_CalMapReadWriteRatio {

    static Thread[] threads = new Thread[Content.THREAD_NUM];

    static UUID[] keys = new UUID[Content.NUM];

    static UUID[] values = new UUID[Content.NUM];

    static Hashtable<UUID, UUID> hashtable = new Hashtable<>();

    static HashMap<UUID, UUID> hashMap = new HashMap<>();

    static Map<UUID, UUID> synchronizedMap = Collections.synchronizedMap(new HashMap<UUID, UUID>());

    static ConcurrentHashMap<UUID,UUID> concurrentHashMap = new ConcurrentHashMap<>();

    static {
        for (int i = 0; i < Content.NUM; i++) {
            keys[i] = UUID.randomUUID();
            values[i] = UUID.randomUUID();
        }
    }

    static class MyThread extends Thread {
        int start;
        int count = Content.NUM / Content.THREAD_NUM;
        Map<UUID,UUID> map;

        public MyThread(int start,Map map) {
            this.start = start;
            this.map = map;
        }

        @Override
        public void run() {
            for (int i = start; i < count + start; i++) {
                map.put(keys[i], values[i]);
            }
        }
    }

    public static void main(String[] args) {

//        calMap(hashMap);
//        calMap(concurrentHashMap);
//        calMap(synchronizedMap);
        calMap(hashtable);


    }

    private static void calMap(Map map) {

        // 写
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < Content.THREAD_NUM; i++) {
            threads[i] = new MyThread(i * (Content.NUM / Content.THREAD_NUM),map);
        }
        for (Thread t : threads) {
            t.start();
        }
        for (Thread t : threads) {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println(map.getClass().getName() + " 写入耗时：" + (endTime - startTime) + ",共计写入：" + map.size());

        // 读
        startTime = System.currentTimeMillis();
        for (int i = 0; i < Content.THREAD_NUM; i++) {
            threads[i] = new Thread(()->{
                for (int j = 0; j < Content.NUM; j++) {
                    map.get(keys[10]);
                }
            });
        }
        for (Thread thread : threads) {
            thread.start();
        }
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        endTime = System.currentTimeMillis();
        System.out.println(map.getClass().getName() + " 读耗时：" + (endTime - startTime) );
    }
}
